import { Scene } from '@babylonjs/core/scene';
import { AbstractControl, IAbstractControlOptions } from './abstract-control';
import { Control } from '@babylonjs/gui/2D/controls/control';
import { CreateHandleTo, IHandle, RemoveHandle } from '../../data/data-handle';
import { Checkbox } from '@babylonjs/gui/2D/controls/checkbox';
import { TextBlock } from '@babylonjs/gui/2D/controls/textBlock';
import { StackPanel } from '@babylonjs/gui/2D/controls/stackPanel';


/**
 * 复选框控件参数对象
 * @param isVertical 是否纵向布局
 * @param isChecked 是否选中
 * @param title 标题内容
 * @param fontSize 文字大小
 * @param fontColor 文字颜色
 * @param fontFamily 字体
 * @param checkboxSize 复选框大小
 * @param textHorizontalAlignment 文字水平布局
 * @param textVerticalAlignment 文字垂直布局
 * @param checkboxBackground 复选框背景颜色
 * @param checkboxColor 复选框颜色
 * @param debug 是否开启调试（开发中使用）
 * @param spacing 文字与按钮的间隔留白
 */
interface IUICheckboxOptions extends IAbstractControlOptions {
    isVertical?: boolean,
    isChecked?: boolean,
    title?: string,
    fontSize?: number,
    fontColor?: string,
    fontFamily?: string,
    checkboxSize?: number,
    textHorizontalAlignment?: number,
    textVerticalAlignment?: number,
    checkboxBackground?: string,
    checkboxColor?: string,
    debug?: boolean,
    spacing?: number,
}


/**
 * 复选框控件
 * @param name 名称
 * @param scene 所在场景
 * @param options 参数对象
 */
class UICheckbox extends AbstractControl {

    private _changeHandles: Array<IHandle<boolean>> = [];

    /**
     * 原始复选框控件
     */
    public checkbox!: Checkbox;

    /**
     * 原始标题文字控件
     */
    public header!: TextBlock;

    constructor(name: string, scene: Scene, options?: IUICheckboxOptions) {
        super(name, scene, options);
        this.checkbox.onPointerDownObservable.add(this.breakCamera);
        this.header.onPointerDownObservable.add(this.breakCamera);
    }

    public set isEnabled(enabled: boolean) {
        this.checkbox.isEnabled = enabled;
        if (this.enabledStyle) this.enabledStyle(enabled, this);
    }
    public get isEnabled(): boolean {
        return this.checkbox.isEnabled;
    }

    /**
     * 设置是否选中
     */
    public set isChecked(isChecked: boolean) {
        if (!this.isEnabled) return;
        this.checkbox.isChecked = isChecked;
    }

    /**
     * 获取是否选中
     */
    public get isChecked(): boolean {
        return this.checkbox.isChecked;
    }

    /**
     * 添加选中状态改变时的回调函数对象
     * @param func 回调函数
     * @returns 回调函数对象
     */
    public onChange(func: { (isChecked: boolean): void }): IHandle<boolean> {
        return CreateHandleTo(func, this._changeHandles);
    }

    /**
     * 移除选中状态改变时的回调函数对象
     * @param handle 回调函数对象或其id
     */
    public removeChangeHandle(handle: number | IHandle<boolean>): void {
        RemoveHandle(handle, this._changeHandles);
    }

    protected initializeControl(name: string, scene: Scene, options: IUICheckboxOptions): Control {

        const fontSize = options.fontSize || 26;

        const panel = new StackPanel(name + '-panel');
        panel.isVertical = options.isVertical || false;
        if (options.debug) panel.background = '#ff00ff';

        const checkbox = new Checkbox(name + '-checkbox');
        checkbox.width = (options.checkboxSize || fontSize) + 'px';
        checkbox.height = checkbox.width;
        checkbox.isChecked = options.isChecked || false;
        checkbox.thickness = 1e-6;
        checkbox.color = options.checkboxColor || '#ffffff';
        checkbox.background = options.checkboxBackground || '#000000';

        this.checkbox = checkbox;
        panel.addControl(checkbox);

        const header = new TextBlock(name + '-header');
        header.text = options.title || 'checkbox';
        header.fontFamily = options.fontFamily || 'Arial';
        header.fontSize = fontSize;
        header.color = options.fontColor || '#000000';
        header.width = fontSize + 'px';
        header.height = fontSize + 'px';
        header.clipContent = false;
        this.header = header;
        panel.addControl(header);

        const space = options.spacing || 5;
        UICheckbox.autoLayout(panel, header, space, [header], [checkbox]);

        return panel;
    }

    protected bindEvent(control: Control, options: IUICheckboxOptions): void {
        (control as StackPanel).onPointerClickObservable.add(() => {
            if (!this.isEnabled) return;
            this.checkbox.isChecked = !this.checkbox.isChecked;
        });

        this.checkbox.onIsCheckedChangedObservable.add((isChecked: boolean) => {
            if (!this.isEnabled) return;
            if (!this.avoidEventHandle) this._changeHandles.forEach(handle => handle.callback(isChecked));
        });
    }

    protected unbindEvent(control: Control): void {
        super.unbindEvent(control);
        (control as StackPanel).onPointerClickObservable.clear();
        this.checkbox.onIsCheckedChangedObservable.clear();
    }

}


/**
 * 创建复选框控件
 * @param name 名称
 * @param scene 所在场景
 * @param options 参数对象
 * @param changeCallback 选中状态改变时的回调函数
 * @returns 复选框控件
 */
const CreateUICheckbox = (name: string, scene: Scene, options?: IUICheckboxOptions, changeCallback?: { (isChecked: boolean): void }): UICheckbox => {
    const check = new UICheckbox(name, scene, options);
    if (changeCallback) check.onChange(changeCallback);
    return check;
};


export { UICheckbox, CreateUICheckbox };
export type { IUICheckboxOptions };